/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ssp.net;

import java.util.ArrayList;
import java.util.List;
import ssp.topology.Node;

/**
 * ネットワークコンポーネント内のリソースを管理するクラス
 * @author yamazaki
 */
public class NWresourceManager {
    
    /**
     * NWresourceEntryのリスト
     */
    private List<NWresourceEntry> nwResourceList;
    
    /**
     * コンストラクタ
     */
    public NWresourceManager() {
        this.nwResourceList = new ArrayList<NWresourceEntry>();
    }
    
    /**
     * 指定のネットワークコンポーネントを両端に持つNWresourceEntryを探索する
     * @param c1 隣接ネットワークコンポーネント
     * @param c2 隣接ネットワークコンポーネント
     * @return 見つかったNWresourceEntry
     */
    public NWresourceEntry searchEntry(Node c1, Node c2) {
        for(NWresourceEntry entry : nwResourceList) {
            if(entry.getConnectedNWcomponents().contains(c1) && entry.getConnectedNWcomponents().contains(c2)) {
                return entry;
            }
        }
        throw new IllegalArgumentException();
    }
    
    /**
     * 新たにNWresourceEntryを管理に加える
     * @param enrty NWresourceEntry
     */
    public void addNWresourceEntry(NWresourceEntry enrty) {
        nwResourceList.add(enrty);
    }
    
    /**
     * 管理中のNWresourceEntryを削除する
     * @param entry NWresourceEntry
     */
    public void removeNWresourceEntry(NWresourceEntry entry) {
        nwResourceList.remove(entry);
    }
    
    /**
     * 管理しているNWresourceEntry数を返す
     * @return 管理しているNWresourceEntry数
     */
    public int getEntryNum() {
        return this.nwResourceList.size();
    }
    
    /**
     * 指定のネットワークコンポーネントを結ぶ経路に指定の帯域を予約する
     * @param c1 隣接ネットワークコンポーネント
     * @param c2 隣接ネットワークコンポーネント
     * @param bandwidth 予約する通信帯域
     */
    public void reserveResources(Node c1, Node c2, double bandwidth) {
        NWresourceEntry entry = searchEntry(c1, c2);
        int delta = (int)(bandwidth / entry.getBandwidthUnit());
        if(entry.reserveResources(delta)) {
            //@todo lost
        }
    }
    
    /**
     * 指定のネットワークコンポーネントを結ぶ経路で予約していたリソースを解放する
     * @param c1 隣接ネットワークコンポーネント
     * @param c2 隣接ネットワークコンポーネント
     * @param bandwidth 解放する通信帯域
     */
    public void releaseResources(Node c1, Node c2, double bandwidth) {
        NWresourceEntry entry = searchEntry(c1, c2);
        int delta = (int)(bandwidth / entry.getBandwidthUnit());
        entry.releaseResources(delta);
    }
    
    /**
     * 指定の2ノード間の利用料金を返す
     * @param c1 両端のネットワークコンポーネント
     * @param c2 両端のネットワークコンポーネント
     * @param bandwidth 利用帯域
     * @return 利用料金
     */
    public double getCharge(Node c1, Node c2, double bandwidth) {
        return searchEntry(c1, c2).getCharge(bandwidth);
    }
    
}
